Bulletproof your Application: How to Create a Secure and Exclusive Connection between Amazon CloudFront and Application Load Balancer
Introduction:
Have you ever wished to be sure that your website or application can only be accessed over a secure connection and from your CloudFront distribution? In this blog article, we will walk you through the steps to accomplishing this by establishing an Application Load Balancer (ALB) to accept only CloudFront traffic.
Steps:
Step 1: Configure your ALB for HTTPS/SSL. For a secure connection, set your ALB to use HTTPS/SSL. You can get an SSL certificate from a reliable certificate authority (CA) and install it yourself, or you may utilise ACM. This ensures that the traffic on your website or application is encrypted and cannot be intercepted. Create ACM
elbCertificate:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName: nfs.classmethod.info
ValidationMethod: DNS
SubjectAlternativeNames:
- "*.xxx.xxxxx.com"
DomainValidationOptions:
- DomainName: xxx.xxxxx.com
ValidationDomain: xxx.xxxxx.com
- DomainName: "*.xxx.xxxxxx.com"
ValidationDomain: xxx.xxxxx.com
Tags:
- Key: "Name"
Value: !Sub $devio-elb-acm
Use the above output ARN in ALB listener.
Listener:
Type: "AWS::ElasticLoadBalancingV2::Listener"
Properties:
DefaultActions:
- TargetGroupArn: !Ref TargetGroup
Type: forward
LoadBalancerArn: !Ref ALB
Port: 443
Protocol: HTTPS
Certificates:
- CertificateArn: arn:aws:acm:ap-northeast-1:xxxxxxxxx:certificate/dxxxxxxxxxxxxxxxxxx
SslPolicy: ELBSecurityPolicy-2016-08
Step 2: Construct a CloudFront distribution. Then, for your ALB, establish a CloudFront distribution and set it to utilise HTTPS/SSL. You can also utilise an SSL certificate issued by a reputable CA for this purpose or ACM use the us-east-1 region. This ensures that all communication between your users and CloudFront is secured.
Create the ACM in use-east-1 using same way as done in ALB * CloudFormation Snippet for constructing CloudFront distribution:
Resources:
# ------------------------------------------------------------#
# CloudFront
# ------------------------------------------------------------#
CloudFront:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
IPV6Enabled: false
Logging:
Bucket:*****.s3.amazonaws.com
IncludeCookies: false
Prefix: !Sub '${SystemName}-${EnvType}-cloudfront-logs/'
Aliases:
- 'xxxx.xxx.xxxxx.com'
ViewerCertificate:
AcmCertificateArn: arn:aws:acm:us-east-1:xxxxxxxxx:certificate/dxxxxxxxxxxxxxxxxxx
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
CachedMethods:
- GET
- HEAD
CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6
TargetOriginId: elbOrigin
ViewerProtocolPolicy: https-only
Enabled: true
Origins:
- Id: elbOrigin
DomainName: xxx.xxx.xxxxxxxx.com
CustomOriginConfig:
HTTPSPort: '443'
OriginProtocolPolicy: https-only
PriceClass: PriceClass_All
Step 3: Specify the ALB as the origin server In your CloudFront distribution, specify the ALB as the origin server. This will ensure that CloudFront forwards the requests to your ALB.
Origins:
- Id: elbOrigin
DomainName: xxx.xxx.xxxxxxxx.com
CustomOriginConfig:
HTTPSPort: '443'
OriginProtocolPolicy: https-only
Step 4: Configure your ALB to accept traffic only from CloudFront Now, it's time to restrict access to your ALB. Create a security group that allows inbound traffic only from the CloudFront CIDR block(use managed prefix list), and assign it to the ALB. This will ensure that your ALB only accepts traffic from CloudFront, and no one can directly access your ALB.
Resources:
ElbSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: dev-io-elb-sg
GroupDescription: devio-elb-sg
VpcId: network-template-VPCID
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
SourcePrefixListId: pl-58a04531
Tags:
- Key: Name
Value: devio-elb-sg
Step 5: Send the Host header to the ALB. To ensure that the traffic is coming from CloudFront, send the Host header to the ALB. Enabling the "Forward Headers" option in CloudFront and choosing the "Whitelist" option will do this. Next, include the "Host" header in your whitelist.
OriginCustomHeaders
HeaderName: String
HeaderValue: String
Step 6: (Optional) For further security, use Amazon WAF. You may optionally utilise Amazon WAF to give an extra degree of protection to your ALB. You can prohibit any traffic that does not fit your stated criteria by creating a web ACL. You can, for example, block requests that contain dangerous SQL injection attempts. Cloudformation Snipets for Creating WAF And associating it with ALB
WebACL:
Type: AWS::WAFv2::WebACL
Properties:
Name: devio-webacl-alb'
DefaultAction:
Block: {}
Description: AWS WAFv2 WebACL
Scope: REGIONAL
VisibilityConfig:
CloudWatchMetricsEnabled: true
MetricName: !Sub '${SystemName}-${EnvName}-webacl-alb'
SampledRequestsEnabled: true
Rules:
- Name: AWS-AWSManagedRulesAnonymousIpList
Priority: 1
Statement:
ManagedRuleGroupStatement:
VendorName: AWS
Name: AWSManagedRulesAnonymousIpList
OverrideAction:
Block: {}
VisibilityConfig:
CloudWatchMetricsEnabled: true
MetricName: !Sub '${SystemName}-${EnvType}-AWSManagedRulesAnonymousIpList'
SampledRequestsEnabled: true
Conclusion:
By following these steps, you can ensure that your website or application is accessible only through a secure connection and only from your CloudFront distribution.